home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PXDTUT3.ZIP / PXDTUT3.PAS < prev    next >
Pascal/Delphi Source File  |  1997-06-01  |  19KB  |  778 lines

  1. program PXDTUT3;
  2.  
  3. uses
  4.  crt;
  5.  
  6. CONST
  7.  VGA = $a000;
  8.  
  9.  Num_of_points = 8;
  10.  Num_of_faces = 6;
  11.  
  12.  Xofs = 160;
  13.  yofs = 100;
  14.  Zeye = -200;
  15.  
  16.  
  17. TYPE
  18.   PointT = record
  19.              x,y,z : integer;
  20.           end;                                {6 bytes pr point}
  21.  
  22.   ScrPointT = record
  23.                x,y : integer;                 {4 bytes pr point}
  24.              end;
  25.  
  26.   FaceT = record
  27.            P1,P2,P3,P4 : integer;             {9 bytes pr face}
  28.            color  : byte;
  29.          end;
  30.  
  31.  
  32.   PointRecord    = Array[1..Num_of_points] of PointT;    {points *  6 bytes}
  33.   FaceRecord     = Array[1..Num_of_faces] of FaceT;      {faces  *  9 bytes}
  34.   ScrPointRecord = Array[1..Num_of_points] of ScrPointT; {points *  4 bytes}
  35.   CenterRecord   = Array[1..Num_of_faces] of integer;    {faces  *  2 bytes}
  36.  
  37.   Virtualscreen = Array[1..64000] of byte;
  38.   Virscr = ^VirtualScreen;
  39.  
  40. VAR
  41.  lookup     : Array [0..360,1..2] of integer; {Our sin and cos lookup table}
  42.  Baseobj    : PointRecord;       {original 3d-object}
  43.  Faces      : FaceRecord;        {data for how faces is defined}
  44.  Points     : PointRecord;       {rotated 3d-object}
  45.  Translated : ScrPointRecord;    {the 2d-screenpoints for drawing}
  46.  Centers    : CenterRecord;      {Z-val of centers for depth sorting}
  47.  OrderTable : Array[1..Num_of_faces] of integer; {how to handle faces correct}
  48.  
  49.  Xrot,Yrot, Zrot : integer;
  50.  scr2 : virscr;
  51.  vaddr : word;
  52.  
  53.  
  54. PROCEDURE WaitRetrace;
  55. Assembler;
  56. label l1,l2;
  57.  
  58. asm
  59.  mov dx,3DAh
  60. l1:
  61.   in al,dx
  62.   and al,08h
  63.   jnz l1
  64. l2:
  65.   in al,dx
  66.   and al,08h
  67.   jz l2
  68. END;
  69.  
  70.  
  71. Procedure FlipScreen(source, dest : word);
  72. Assembler; {386 only}
  73. asm
  74.   mov     dx, ds
  75.   mov     ax, [dest]
  76.   mov     es, ax
  77.   mov     ax, [source]
  78.   mov     ds, ax
  79.   xor     si, si
  80.   xor     di, di
  81.   mov     cx, 16000
  82.   db      $66
  83.   rep     movsw
  84.   mov     ds,dx    {mov's are faster than push / pops }
  85. end;
  86.  
  87. Procedure Clear (Col : Byte;where:word);
  88. Assembler;
  89.      asm
  90.         mov     cx, 32000;
  91.         mov     ax,where
  92.         mov     es,ax
  93.         xor     di,di
  94.         mov     al,[col]
  95.         mov     ah,al
  96.         rep     stosw
  97.       END;
  98.  
  99. Procedure PurplePal;
  100. var
  101.  taeller : integer;
  102. begin
  103.  for taeller := 0 to 63 do
  104.    begin   {63 shades from black to purple}
  105.     port[$3C8] := taeller;
  106.     port[$3C9] := taeller;
  107.     port[$3C9] := 0;
  108.     port[$3C9] := taeller;
  109.    end;
  110. end;
  111.  
  112.  
  113.  
  114. Procedure HorLine(Xbegin, Xend,Ypos : integer;color : byte;where : word);
  115. Assembler;
  116. asm
  117.  mov cx,[Xend]
  118.  inc cx
  119.  sub cx,[Xbegin]   {cx = length of line - used for counter }
  120.                    {note, I assume that Xbegin < Xend - the poly routine}
  121.                    {will take care of that...}
  122.  mov ax,[ypos]
  123.  shl ax,8
  124.  mov di,ax
  125.  shr ax,2
  126.  add di,ax
  127.  add di,[Xbegin]   {di = Ypos * 320 + Xbegin - offset for our line}
  128.  mov es,[where]    {where to draw..}
  129.  
  130.  mov al,[color]
  131.  rep stosb         {I draw byte by byte - slower than drawing a word at a}
  132.                    {time but it is because of the changes we are going to}
  133.                    {make to this routine when glenzing/gouraud/texturemapping}
  134. end;
  135.  
  136.  
  137. PROCEDURE GlenzHorline(xb,xe,y:integer; c:byte;where : word); assembler;
  138. asm
  139.   mov bx,[xb]
  140.   mov cx,[xe]
  141.   inc cx
  142.   sub cx,bx             { length of line in cx }
  143.   mov es,Where         { segment to draw in }
  144.   mov ax,[y]            { heigth of line }
  145.   shl ax,8
  146.   mov di,ax
  147.   shr ax,2
  148.   add di,ax             { y*320 in di (offset) }
  149.   add di,bx             { add x-begin }
  150.  
  151.  @again:
  152.   mov al,es:[di]
  153.   add al,[c]
  154.   stosb
  155.   dec cx
  156.   cmp cx,0
  157.   jne @again
  158.  @out:
  159. end;
  160.  
  161.  
  162.  
  163. Procedure Polygon(X1,Y1,X2,Y2,X3,Y3,X4,Y4 : integer;color : byte; where : word);
  164. var
  165.  counter : integer;
  166.  Ymin, Ymax : integer;
  167.  polygon : Array[0..199,1..2] of integer;
  168.  
  169. Procedure ScanPolySide(X1,Y1,X2,Y2 : integer);
  170. var
  171.  DeltaX : integer;
  172.  temp : integer;
  173.  Xposfixed,Xpos : integer;
  174.  counter : integer;
  175. begin
  176.   if Y2=Y1 then exit;          {exit if side is a horizontal line }
  177.   if (Y2<Y1) then              {make sure Y1 is top point}
  178.                begin
  179.                  temp := Y1;
  180.                  Y1 := Y2;
  181.                  Y2 := temp;
  182.  
  183.                  temp := X1;
  184.                  X1 := X2;
  185.                  X2 := temp;   {switch the points if Y1 is not top..}
  186.                end;
  187.  
  188.   DeltaX := ((X2-X1) shl 7) div (Y2-Y1); {DeltaX in 9.7 fixed point math}
  189.   Xposfixed := X1 shl 7; {Xpos in 9.7 fixed point math }
  190.     for counter := Y1 to Y2 do
  191.          begin
  192.            Xpos := XposFixed shr 7;
  193.            if (Xpos < polygon[counter,1]) then polygon[counter,1] := Xpos;
  194.            if (Xpos > polygon[counter,2]) then polygon[counter,2] := Xpos;
  195.            Xposfixed := XposFixed + DeltaX;
  196.          end;
  197. end;
  198.  
  199.  
  200. begin
  201.  Ymin := Y1;
  202.  Ymax := Y1;
  203.  if (Y2 < Ymin) then Ymin := Y2;
  204.  if (Y2 > Ymax) then Ymax := Y2;
  205.  if (Y3 < Ymin) then Ymin := Y3;
  206.  if (Y3 > Ymax) then Ymax := Y3;
  207.  if (Y4 < Ymin) then Ymin := Y4;
  208.  if (Y4 > Ymax) then Ymax := Y4;  {what is Ymin and Ymax in this polygon ?}
  209.  
  210.  if (Ymin < 0) then Ymin := 0;
  211.  if (Ymax > 199) then Ymax := 199;
  212.  
  213.  for counter := 0 to 199 do
  214.    begin
  215.      polygon[counter,1] := 32000;
  216.      polygon[counter,2] := -32000;
  217.    end;
  218.  
  219.  {we have to initialize our variable 'polygon' to some extreme values}
  220.  
  221.  ScanPolySide(X1,Y1,X2,Y2);
  222.  ScanPolySide(X2,Y2,X3,Y3);
  223.  ScanPolySide(X3,Y3,X4,Y4);
  224.  ScanPolySide(X4,Y4,X1,Y1); {all four sides scanned}
  225.  
  226.  for counter := Ymin to Ymax do
  227.     Horline(polygon[counter,1],polygon[counter,2],counter,color,where);
  228. end;
  229.  
  230.  
  231. Procedure GlenzPolygon(X1,Y1,X2,Y2,X3,Y3,X4,Y4 : integer;color : byte; where : word);
  232. var
  233.  counter : integer;
  234.  Ymin, Ymax : integer;
  235.  polygon : Array[0..199,1..2] of integer;
  236.  
  237. Procedure ScanPolySide(X1,Y1,X2,Y2 : integer);
  238. var
  239.  DeltaX : integer;
  240.  temp : integer;
  241.  Xposfixed,Xpos : integer;
  242.  counter : integer;
  243. begin
  244.   if Y2=Y1 then exit;          {exit if side is a horizontal line }
  245.   if (Y2<Y1) then              {make sure Y1 is top point}
  246.                begin
  247.                  temp := Y1;
  248.                  Y1 := Y2;
  249.                  Y2 := temp;
  250.  
  251.                  temp := X1;
  252.                  X1 := X2;
  253.                  X2 := temp;   {switch the points if Y1 is not top..}
  254.                end;
  255.  
  256.   DeltaX := ((X2-X1) shl 7) div (Y2-Y1); {DeltaX in 9.7 fixed point math}
  257.   Xposfixed := X1 shl 7; {Xpos in 9.7 fixed point math }
  258.     for counter := Y1 to Y2 do
  259.          begin
  260.            Xpos := XposFixed shr 7;
  261.            if (Xpos < polygon[counter,1]) then polygon[counter,1] := Xpos;
  262.            if (Xpos > polygon[counter,2]) then polygon[counter,2] := Xpos;
  263.            Xposfixed := XposFixed + DeltaX;
  264.          end;
  265. end;
  266.  
  267.  
  268. begin
  269.  Ymin := Y1;
  270.  Ymax := Y1;
  271.  if (Y2 < Ymin) then Ymin := Y2;
  272.  if (Y2 > Ymax) then Ymax := Y2;
  273.  if (Y3 < Ymin) then Ymin := Y3;
  274.  if (Y3 > Ymax) then Ymax := Y3;
  275.  if (Y4 < Ymin) then Ymin := Y4;
  276.  if (Y4 > Ymax) then Ymax := Y4;  {what is Ymin and Ymax in this polygon ?}
  277.  
  278.  if (ymin < 0) then Ymin := 0;
  279.  if (Ymax > 199) then Ymax := 199;
  280.  
  281.  for counter := 0 to 199 do
  282.    begin
  283.      polygon[counter,1] := 32000;
  284.      polygon[counter,2] := -32000;
  285.    end;
  286.  
  287.  {we have to initialize our variable 'polygon' to some extreme values}
  288.  
  289.  ScanPolySide(X1,Y1,X2,Y2);
  290.  ScanPolySide(X2,Y2,X3,Y3);
  291.  ScanPolySide(X3,Y3,X4,Y4);
  292.  ScanPolySide(X4,Y4,X1,Y1); {all four sides scanned}
  293.  
  294.  for counter := Ymin to Ymax do
  295.     GlenzHorline(polygon[counter,1],polygon[counter,2],counter,color,where);
  296. end;
  297.  
  298.  
  299.  
  300. PROCEDURE SetUpVirtual(VAR screenname:virscr;VAR add : word);
  301. BEGIN
  302.   GetMem (Screenname,64000);
  303.   add := seg (Screenname^);
  304.   clear(0,add);
  305. END;
  306.  
  307. PROCEDURE ShutDown(Screenname:virscr);
  308. BEGIN
  309.   FreeMem (Screenname,64000);
  310. END;
  311.  
  312.  
  313. Function rad (theta : real) : real;
  314. BEGIN
  315.   rad := theta * pi / 180
  316. END;
  317.  
  318. Procedure Calc_Cos_sin;
  319. var
  320.  loop1 : integer;
  321. begin
  322.  For loop1:=0 to 360 do
  323.    BEGIN
  324.     lookup [loop1,1]:=round(sin (rad (loop1))*16384);
  325.     lookup [loop1,2]:=round(cos (rad (loop1))*16384);
  326.    END;
  327. end;
  328.  
  329. FUNCTION Xconv(X,Z : integer):integer;
  330. BEGIN
  331.  Xconv:=Xofs+Round(X*(Zeye/(Zeye-Z)));
  332. END;
  333.  
  334. FUNCTION Yconv(Y,Z : integer):integer;
  335. BEGIN
  336.  Yconv:=Yofs+Round(Y*(Zeye/(Zeye-Z)));
  337. END;
  338.  
  339. Procedure Init_Object;
  340. var
  341.  taeller : integer;
  342. begin
  343.   baseobj[1].X := -50;
  344.   baseobj[1].Y := -50;
  345.   baseobj[1].Z := -50;
  346.  
  347.   baseobj[2].X :=  50;
  348.   baseobj[2].Y := -50;
  349.   baseobj[2].Z := -50;
  350.  
  351.   baseobj[3].X := -50;
  352.   baseobj[3].Y :=  50;
  353.   baseobj[3].Z := -50;
  354.  
  355.   baseobj[4].X :=  50;
  356.   baseobj[4].Y :=  50;
  357.   baseobj[4].Z := -50;
  358.  
  359.   baseobj[5].X := -50;
  360.   baseobj[5].Y := -50;
  361.   baseobj[5].Z :=  50;
  362.  
  363.   baseobj[6].X :=  50;
  364.   baseobj[6].Y := -50;
  365.   baseobj[6].Z :=  50;
  366.  
  367.   baseobj[7].X := -50;
  368.   baseobj[7].Y :=  50;
  369.   baseobj[7].Z :=  50;
  370.  
  371.   baseobj[8].X :=  50;
  372.   baseobj[8].Y :=  50;
  373.   baseobj[8].Z :=  50;
  374.  
  375.   faces[1].P1 :=   1;
  376.   faces[1].P2 :=   2;
  377.   faces[1].P3 :=   4;
  378.   faces[1].P4 :=   3;
  379.  
  380.   faces[2].P1 :=   2;
  381.   faces[2].P2 :=   6;
  382.   faces[2].P3 :=   8;
  383.   faces[2].P4 :=   4;
  384.  
  385.   faces[3].P1 :=   5;
  386.   faces[3].P2 :=   7;
  387.   faces[3].P3 :=   8;
  388.   faces[3].P4 :=   6;
  389.  
  390.   faces[4].P1 :=   1;
  391.   faces[4].P2 :=   3;
  392.   faces[4].P3 :=   7;
  393.   faces[4].P4 :=   5;
  394.  
  395.   faces[5].P1 :=   1;
  396.   faces[5].P2 :=   5;
  397.   faces[5].P3 :=   6;
  398.   faces[5].P4 :=   2;
  399.  
  400.   faces[6].P1 :=   3;
  401.   faces[6].P2 :=   4;
  402.   faces[6].P3 :=   8;
  403.   faces[6].P4 :=   7;
  404.  
  405.   for taeller := 1 to Num_of_faces do
  406.      faces[taeller].color :=  0 + taeller * 3;
  407. end;
  408.  
  409. Procedure RotatePoint (Xrot,Yrot,Zrot,Xin,Yin,Zin:Integer;var Xout,Yout,Zout : integer);
  410. VAR
  411.   a,b,c:integer;
  412. BEGIN
  413.       b:=lookup[Yrot,2];
  414.       c:=Xin;
  415.       asm
  416.         mov   ax,b
  417.         imul  c
  418.         sal   ax,1
  419.         rcl   dx,1
  420.         sal   ax,1
  421.         rcl   dx,1
  422.         mov   a,dx
  423.       end;
  424.       b:=lookup[Yrot,1];
  425.       c:=Zin;
  426.       asm
  427.         mov   ax,b
  428.         imul  c
  429.         sal   ax,1
  430.         rcl   dx,1
  431.         sal   ax,1
  432.         rcl   dx,1
  433.         add   a,dx
  434.       end;
  435.       Xout:=a;
  436.       Yout:=Yin;
  437.       b:=-lookup[Yrot,1];
  438.       c:=Xin;
  439.       asm
  440.         mov   ax,b
  441.         imul  c
  442.         sal   ax,1
  443.         rcl   dx,1
  444.         sal   ax,1
  445.         rcl   dx,1
  446.         mov   a,dx
  447.       end;
  448.       b:=lookup[Yrot,2];
  449.       c:=Zin;
  450.       asm
  451.         mov   ax,b
  452.         imul  c
  453.         sal   ax,1
  454.         rcl   dx,1
  455.         sal   ax,1
  456.         rcl   dx,1
  457.         add   a,dx
  458.       end;
  459.       Zout:=a;
  460.  
  461.   if (Xrot<>0) THEN
  462.      BEGIN
  463.         b:=lookup[Xrot,2];
  464.         c:=Yout;
  465.         asm
  466.           mov   ax,b
  467.           imul  c
  468.           sal   ax,1
  469.           rcl   dx,1
  470.           sal   ax,1
  471.           rcl   dx,1
  472.           mov   a,dx
  473.         end;
  474.         b:=lookup[Xrot,1];
  475.         c:=Zout;
  476.         asm
  477.           mov   ax,b
  478.           imul  c
  479.           sal   ax,1
  480.           rcl   dx,1
  481.           sal   ax,1
  482.           rcl   dx,1
  483.           sub   a,dx
  484.         end;
  485.         b:=lookup[Xrot,1];
  486.         c:=Yout;
  487.         Yout:=a;
  488.         asm
  489.           mov   ax,b
  490.           imul  c
  491.           sal   ax,1
  492.           rcl   dx,1
  493.           sal   ax,1
  494.           rcl   dx,1
  495.           mov   a,dx
  496.         end;
  497.         b:=lookup[Xrot,2];
  498.         c:=Zout;
  499.         asm
  500.           mov   ax,b
  501.           imul  c
  502.           sal   ax,1
  503.           rcl   dx,1
  504.           sal   ax,1
  505.           rcl   dx,1
  506.           add   a,dx
  507.         end;
  508.         Zout:=a;
  509.      END; {if Xrot <> 0 }
  510.  
  511.  
  512.  if (Zrot<>0) THEN
  513.      BEGIN
  514.         b:=lookup[Zrot,2];
  515.         c:=Xout;
  516.         asm
  517.           mov   ax,b
  518.           imul  c
  519.           sal   ax,1
  520.           rcl   dx,1
  521.           sal   ax,1
  522.           rcl   dx,1
  523.           mov   a,dx
  524.         end;
  525.         b:=lookup[Zrot,1];
  526.         c:=Yout;
  527.         asm
  528.           mov   ax,b
  529.           imul  c
  530.           sal   ax,1
  531.           rcl   dx,1
  532.           sal   ax,1
  533.           rcl   dx,1
  534.           sub   a,dx
  535.         end;
  536.         b:=lookup[Zrot,1];
  537.         c:=Xout;
  538.         Xout:=a;
  539.         asm
  540.           mov   ax,b
  541.           imul  c
  542.           sal   ax,1
  543.           rcl   dx,1
  544.           sal   ax,1
  545.           rcl   dx,1
  546.           mov   a,dx
  547.         end;
  548.         b:=lookup[Zrot,2];
  549.         c:=Yout;
  550.         asm
  551.           mov   ax,b
  552.           imul  c
  553.           sal   ax,1
  554.           rcl   dx,1
  555.           sal   ax,1
  556.           rcl   dx,1
  557.           add   a,dx
  558.         end;
  559.         Yout:=a;
  560.      END; {if Zrot <> 0 }
  561. END; {This one I grapped from some Asphyxia tuturial.... thnx Denthor }
  562.  
  563.  
  564.  
  565. Procedure Rotateobj(x,y,z : integer);
  566. {Rotates all points and calculates center Z-val for sorting}
  567. var
  568.  taeller : integer;
  569. begin
  570.  for taeller := 1 to num_of_points do
  571.   RotatePoint(x,y,z,baseobj[taeller].x,baseobj[taeller].y,baseobj[taeller].z,
  572.               points[taeller].x,points[taeller].y,points[taeller].z);
  573.  
  574.  
  575.  for taeller := 1 to num_of_faces do
  576.     centers[taeller] :=
  577.      (points[faces[taeller].P1].Z + points[faces[taeller].P2].Z +
  578.       points[faces[taeller].P3].Z + points[faces[taeller].P4].Z);
  579.     {average Z-val for face. NOTE : SHOULD divide by 4.. but that is really}
  580.     {not nessesary. This way all the values will be the correct val times 4}
  581.     {As ALL values is 4 times too big they will still sort correct :)      }
  582. end;
  583.  
  584.  
  585. Procedure Sort_faces;
  586. {Just a simple bubble-sort - not to fast but what the heck :) }
  587. {Faces with the HIGHEST Z-val is placed first in Order[] }
  588. VAR
  589.   counter : integer;
  590.   position : integer;
  591.   tempval : integer;
  592. BEGIN
  593.   for counter:=1 to Num_of_faces do BEGIN
  594.     OrderTable[counter]:=counter;
  595.   END;
  596.   {we resets the ordertable so that it matches the unsorted 'centers' variable}
  597.   position := 1;
  598.  
  599.   repeat
  600.     if (centers[position] < centers[position+1]) then
  601.         BEGIN   {switch values in centers and ordertable}
  602.           tempval := Centers[position+1];
  603.           Centers[position+1] := centers[position];
  604.           centers[position] := tempval;
  605.  
  606.           tempval := OrderTable[position+1];
  607.           OrderTable[position+1] := OrderTable[position];
  608.           OrderTable[position] := tempval;
  609.  
  610.           position:=1;   {start loop over}
  611.         END;
  612.       inc(position);
  613.   until (position = Num_of_faces);  {all way through without changes}
  614. END;
  615.  
  616.  
  617. Procedure Project_points;
  618. var
  619.  taeller : integer;
  620. begin
  621.  for taeller := 1 to Num_of_points do
  622.     begin
  623.       translated[taeller].X := Xconv(points[taeller].X,points[taeller].Z);
  624.       translated[taeller].Y := Yconv(points[taeller].Y,points[taeller].Z);
  625.      end;
  626. end;
  627.  
  628. Procedure Do_faces(where : word);
  629. {This one can be used for all kinds of fills : solid, textures, glenz...}
  630. var
  631.  taeller : integer;
  632.  X1,Y1,X2,Y2,X3,Y3,X4,Y4 : integer;
  633.  color : byte;
  634.  polynr : integer;
  635.  normal : integer;
  636. begin
  637.  for taeller := 1 to Num_of_faces do
  638.    begin
  639.      polynr := OrderTable[taeller];
  640.      X1 := translated[faces[polynr].P1].X;
  641.      Y1 := translated[faces[polynr].P1].Y;
  642.      X2 := translated[faces[polynr].P2].X;
  643.      Y2 := translated[faces[polynr].P2].Y;
  644.      X3 := translated[faces[polynr].P3].X;
  645.      Y3 := translated[faces[polynr].P3].Y;
  646.      X4 := translated[faces[polynr].P4].X;
  647.      Y4 := translated[faces[polynr].P4].Y;
  648.      color := faces[polynr].color;
  649.  
  650.      {*******************************************************}
  651.      {******* HIDDEN FACE REMOVAL - YES, THAT EASY ;) *******}
  652.      {*******************************************************}
  653.      {Z-Comp of normal}
  654.      normal := (Y1-Y3)*(X2-X1) - (X1-X3)*(Y2-Y1);
  655.        if (normal < 0) then
  656.          Polygon(X1,Y1,X2,Y2,X3,Y3,X4,Y4,color,where);
  657.      {*******************************************************}
  658.      {*******************************************************}
  659.      {*******************************************************}
  660.    end;
  661. end;
  662.  
  663.  
  664. Procedure DoGlenzing(where : word);
  665. var
  666.  taeller : integer;
  667.  X1,Y1,X2,Y2,X3,Y3,X4,Y4 : integer;
  668.  color : byte;
  669. begin
  670.  for taeller := 1 to Num_of_faces do
  671.    begin
  672.      X1 := translated[faces[taeller].P1].X;
  673.      Y1 := translated[faces[taeller].P1].Y;
  674.      X2 := translated[faces[taeller].P2].X;
  675.      Y2 := translated[faces[taeller].P2].Y;
  676.      X3 := translated[faces[taeller].P3].X;
  677.      Y3 := translated[faces[taeller].P3].Y;
  678.      X4 := translated[faces[taeller].P4].X;
  679.      Y4 := translated[faces[taeller].P4].Y;
  680.      color := faces[taeller].color;
  681.  
  682.      GlenzPolygon(X1,Y1,X2,Y2,X3,Y3,X4,Y4,color,where);
  683.    end;
  684. end;
  685.  
  686.  
  687.  
  688. BEGIN
  689.  
  690. Clrscr;
  691. Writeln('      ****************************************************************');
  692. Writeln('      *                                                              *');
  693. Writeln('      *                    3D BASIC OBJECT ENGINE                    *');
  694. Writeln('      *                        by : Telemachos                       *');
  695. Writeln('      *                                                              *');
  696. Writeln('      ****************************************************************');
  697. Writeln;
  698. Writeln;
  699. Writeln('      Hiya! ');
  700. Writeln('      Welcome to the Peroxide Programming Tips #3');
  701. Writeln('      This one is on 3D objects - starting out with the basics of 3D');
  702. Writeln('      programming.');
  703. Writeln;
  704. Writeln('      This small demo contains two small parts. The first is a demo ');
  705. Writeln('      of the theory on face sorting and hidden face removal we learned');
  706. Writeln('      in the textfile.');
  707. Writeln('      The other part is a demo of the glenzing effect.');
  708. Writeln('      Press any key to change from the first to the second part..');
  709. Writeln;
  710. Writeln('      Hit any key to start.....');
  711.  
  712.  
  713. readkey;
  714.  
  715.  asm
  716.    mov ax,13h
  717.    int 10h
  718.  end;
  719.  
  720. SetupVirtual(scr2,vaddr);
  721.  
  722.  
  723. Calc_cos_sin;
  724. Init_Object;
  725.  
  726. Clear(0,VGA);
  727.  
  728. Xrot := 0;
  729. Yrot := 0;
  730. Zrot := 0;
  731.  
  732.  
  733. repeat
  734.  Rotateobj(Xrot,Yrot,Zrot);
  735.  
  736.  Xrot := (Xrot + 2) mod 360;
  737.  Yrot := (Yrot + 4) mod 360;
  738.  Zrot := (Zrot + 1) mod 360;
  739.  Clear(0,Vaddr);
  740.  
  741.  Project_Points;
  742.  Sort_faces;
  743.  Do_faces(Vaddr);
  744.  
  745.  waitretrace;
  746.  FlipScreen(vaddr,VGA);
  747.  
  748. until keypressed;
  749. readkey;
  750.  
  751.  
  752. PurplePal; {set up linear pallette for glenzing... not the best way to glenz}
  753.  
  754. repeat
  755.  Rotateobj(Xrot,Yrot,Zrot);
  756.  
  757.  Xrot := (Xrot + 2) mod 360;
  758.  Yrot := (Yrot + 4) mod 360;
  759.  Zrot := (Zrot + 1) mod 360;
  760.  Clear(0,Vaddr);
  761.  
  762.  Project_Points;
  763.  DoGlenzing(vaddr);
  764.  
  765.  waitretrace;
  766.  FlipScreen(vaddr,VGA);
  767. until keypressed;
  768. readkey;
  769.  
  770.  
  771. ShutDown(scr2);
  772.  
  773. asm
  774.  mov ax,03h
  775.  int 10h
  776. end;
  777.  
  778. END.